package com.xyf.sys.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.gson.Gson;
import com.kuaidi100.sdk.api.LabelV2;
import com.kuaidi100.sdk.contant.ApiInfoConstant;
import com.kuaidi100.sdk.contant.PrintType;
import com.kuaidi100.sdk.core.IBaseClient;
import com.kuaidi100.sdk.pojo.HttpResult;
import com.kuaidi100.sdk.request.PrintReq;
import com.kuaidi100.sdk.request.labelV2.CustomReq;
import com.kuaidi100.sdk.utils.SignUtils;
import com.lop.open.api.sdk.DefaultDomainApiClient;
import com.lop.open.api.sdk.LopException;
import com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCheckPreCreateOrderV1.CommonCheckPreCreateOrderResponse;
import com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCheckPreCreateOrderV1.CommonCreateOrderRequest;
import com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCheckPreCreateOrderV1.Contact;
import com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCreateOrderV1.CommonCreateOrderResponse;
import com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCreateOrderV1.FaceSheetInfo;
import com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCreateOrderV1.FaceSheetResponse;
import com.lop.open.api.sdk.domain.ECAP.CommonModifyCancelOrderApi.commonCancelOrderV1.CommonModifyCancelOrderResponse;
import com.lop.open.api.sdk.domain.ECAP.CommonModifyCancelOrderApi.commonCancelOrderV1.CommonOrderCancelRequest;
import com.lop.open.api.sdk.domain.ECAP.CommonQueryOrderApi.commonGetActualFeeInfoV1.CommonActualFeeResponse;
import com.lop.open.api.sdk.domain.ECAP.CommonQueryOrderApi.commonGetOrderTraceV1.CommonOrderTraceDetail;
import com.lop.open.api.sdk.domain.ECAP.CommonQueryOrderApi.commonGetOrderTraceV1.CommonOrderTraceResponse;
import com.lop.open.api.sdk.domain.ECAP.CommonSubscribeTraceApi.commonSubscribeTraceV1.CommonSubscribeResponse;
import com.lop.open.api.sdk.plugin.LopPlugin;
import com.lop.open.api.sdk.plugin.factory.OAuth2PluginFactory;
import com.lop.open.api.sdk.request.ECAP.*;
import com.lop.open.api.sdk.response.ECAP.*;
import com.xyf.sys.config.CustomConfig;
import com.xyf.sys.config.CustomException;
import com.xyf.sys.config.MiniprogramConfig;
import com.xyf.sys.domain.*;
import com.xyf.sys.enums.DeliveryEnum;
import com.xyf.sys.enums.JTExpressGoodsTypeEnum;
import com.xyf.sys.enums.YunDaLogisticActionEnum;
import com.xyf.sys.enums.YunDaLogisticStatusEnum;
import com.xyf.sys.mapper.OrderMapper;
import com.xyf.sys.service.*;
import com.xyf.sys.util.CallExpressSFHttpUtil;
import com.xyf.sys.util.EMSUtils;
import com.xyf.sys.vo.*;
import com.yl.jms.sdk.JtExpressApi;
import com.yundasys.OpenApiHttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author R-H
 * @Date 2024/2/271731
 * @Description
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class LogisticServiceImpl implements ILogisticService {

    /**
     * 申通
     */
    public static final String STO_URL = "https://cloudinter-linkgateway.sto.cn/gateway/link.do";
    public static final String STO_ORDER_SOURCE = "XYFLL";

    @Value("${kuaidi100.key}")
    public String key;
    @Value("${kuaidi100.secret}")
    public String secret;

    @Autowired
    private CustomConfig.YundaexConfig yundaexConfig;
    @Autowired
    private CustomConfig.STOConfig stoConfig;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private IOrderProductService orderProductService;
    @Autowired
    private IOrderAddressService orderAddressService;
    @Autowired
    private IDeliveryService deliveryService;
    @Autowired
    private IUserPrinterService printerService;
    @Autowired
    private IOrderLogisticsService orderLogisticsService;
    @Autowired
    private IWechatService wechatService;
    @Autowired
    private IUserOrderEventService userOrderEventService;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private JtExpressApi jtExpressApi;
    @Autowired
    private DefaultDomainApiClient defaultDomainApiClient;
    @Autowired
    private IDeptService deptService;
    @Autowired
    private IUserService userService;
    @Autowired
    private ICartItemService cartItemService;
    @Autowired
    private IProductService productService;
    @Autowired
    @Qualifier(value = "clientConfig")
    private MiniprogramConfig.MiniConfig clientConfig;
    @Autowired
    @Qualifier(value = "manageConfig")
    private MiniprogramConfig.MiniConfig manageConfig;

    @Override
    public String searchCount(String appid, String partnerId, String secret, String type) {
        final String url = "https://openapi.yundaex.com/openapi-api/v1/accountOrder/searchCount";
        JSONObject jsonParams = new JSONObject();
        jsonParams.put("appid", appid);
        //韵达白马账号（合作网点提供）
        jsonParams.put("partner_id", partnerId);
        //韵达白马账号的联调密码（合作网点提供）
        jsonParams.put("secret", secret);
        jsonParams.put("type", type == null ? "common" : type);
        log.info("yunda search count param {}", jsonParams);
        return OpenApiHttpUtils.doPostJson(url, jsonParams.toString(), yundaexConfig.getAppkey(), yundaexConfig.getAppSecret());
    }

    @Override
    public String createBmOrder(OrderAddress senderAddress, OrderAddress receiverAddress, BigDecimal weight, String name, String remark) {
        final String url = "https://openapi.yundaex.com/openapi-api/v1/accountOrder/createBmOrder";
        JSONObject jsonParams = new JSONObject();
        jsonParams.put("appid", yundaexConfig.getAppkey());
        Delivery delivery = deliveryService.getConfig("YUNDA");
        jsonParams.put("partner_id", delivery.getBizid());//韵达白马账号（合作网点提供）
        jsonParams.put("secret", delivery.getPassword());//韵达白马账号的联调密码（合作网点提供）
        JSONArray orderList = new JSONArray();
        JSONObject orderItem = new JSONObject();
        String serialNo = "ELEMENT_" + IdUtil.getSnowflakeNextIdStr();
        orderItem.put("order_serial_no", serialNo);
        orderItem.put("khddh", serialNo);
        JSONObject sender = new JSONObject();
        sender.put("name", StringUtils.isNotBlank(senderAddress.getRealName()) && !senderAddress.getRealName().equals(senderAddress.getName()) ? senderAddress.getRealName() + "(" + senderAddress.getName() + ")" : senderAddress.getRealName());
        sender.put("province", senderAddress.getProvince());
        sender.put("city", senderAddress.getCity());
        sender.put("county", senderAddress.getArea());
        sender.put("address", senderAddress.getProvince() + "," + senderAddress.getCity() + "," + senderAddress.getArea() + "," + senderAddress.getTown() + senderAddress.getAddress());
        sender.put("mobile", senderAddress.getMobile());
        orderItem.put("sender", sender);
        JSONObject receiver = new JSONObject();
        receiver.put("name", receiverAddress.getName());
        receiver.put("province", receiverAddress.getProvince());
        receiver.put("city", receiverAddress.getCity());
        receiver.put("county", receiverAddress.getArea());
        receiver.put("address", receiverAddress.getProvince() + "," + receiverAddress.getCity() + "," + receiverAddress.getArea() + "," + receiverAddress.getTown() + receiverAddress.getAddress());
        receiver.put("mobile", receiverAddress.getMobile());
        orderItem.put("receiver", receiver);
        orderItem.put("weight", weight.setScale(2, RoundingMode.HALF_UP));
        JSONArray items = new JSONArray();
        JSONObject item = new JSONObject();
        item.put("name", name);
        item.put("remark", remark);
        items.add(item);
        orderItem.put("items", items);//商品信息集合
        orderItem.put("order_type", "common");// 运单类型参数值对照order_type字典表可固定为common
        orderItem.put("node_id", "350");// 350（默认）
        orderList.add(orderItem);
        jsonParams.put("orders", orderList);
        log.info("yunda create bm order param {}", jsonParams);
        return OpenApiHttpUtils.doPostJson(url, jsonParams.toString(), yundaexConfig.getAppkey(), yundaexConfig.getAppSecret());
    }

    @Override
    public String createEMSOrder(OrderAddress senderAddress, OrderAddress receiverAddress, String contentsAttribute, String cargoName) {
        Delivery delivery = deliveryService.getConfig(DeliveryEnum.EMS.toString());
        JSONArray body = new JSONArray();
        JSONObject order = new JSONObject();
        order.put("ecommerceUserId", "WQENRJFBA");
        order.put("createdTime", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        order.put("logisticsOrderNo", "ELE" + IdUtil.getSnowflakeNextIdStr());
        order.put("contentsAttribute", contentsAttribute.contains("文件") ? "1" : "3");// 1：文件 3、物品 2：信函 4、包裹
        order.put("bizProductNo", "2");// 1.特快专递  2.快递包裹 3.到付 9.即日 10.电商标快 11.标准快递
        JSONObject sender = new JSONObject();
        sender.put("phone", senderAddress.getMobile());
        sender.put("mobile", senderAddress.getMobile());
        sender.put("prov", senderAddress.getProvince());
        sender.put("city", senderAddress.getCity());
        sender.put("county", senderAddress.getArea());
        sender.put("address", senderAddress.getTown() + senderAddress.getAddress());
        sender.put("name", StringUtils.isNotBlank(senderAddress.getRealName()) && !senderAddress.getRealName().equals(senderAddress.getName()) ? senderAddress.getRealName() + "(" + senderAddress.getName() + ")" : senderAddress.getRealName());

        order.put("sender", sender);
        JSONObject receiver = new JSONObject();
        receiver.put("phone", receiverAddress.getMobile());
        receiver.put("mobile", receiverAddress.getMobile());
        receiver.put("prov", receiverAddress.getProvince());
        receiver.put("city", receiverAddress.getCity());
        receiver.put("county", receiverAddress.getArea());
        receiver.put("address", receiverAddress.getTown() + receiverAddress.getAddress());
        receiver.put("name", receiverAddress.getName());
        order.put("receiver", receiver);
        JSONArray cargos = new JSONArray();
        JSONObject cargo = new JSONObject();
        cargo.put("cargoName", cargoName);
        cargos.add(cargo);
        order.put("cargos", cargos);
        body.add(order);
        return EMSUtils.doPost("020003", delivery.getBizid(), delivery.getAuthCode(), body.toJSONString(), delivery.getPassword());
    }

    @Override
    public String createJTOrder(OrderAddress senderAddress, OrderAddress receiverAddress, String txlogisticId, String goodsType, String weight) {
        Delivery config = deliveryService.getConfig(DeliveryEnum.JTSD.toString());
        String url = "https://openapi.jtexpress.com.cn/webopenplatformapi/api/order/addOrder";
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> sender = new HashMap<>();
        Map<String, Object> receiver = new HashMap<>();
        map.put("customerCode", config.getBizid());
        map.put("txlogisticId", txlogisticId);
        map.put("expressType", config.getAuthCode() == null ? "EZ" : config.getAuthCode());//EZ(标准快递)TYD(兔优达)
        map.put("orderType", "1");
        map.put("isRealName", true);
        map.put("serviceType", "02");//服务类型 ：02 门店寄件 ； 01 上门取件
        map.put("deliveryType", "03");//派送类型： 06 代收点自提 05 快递柜自提 04 站点自提 03 派送上门
        map.put("payType", "PP_PM");//支付方式：PP_PM("寄付月结"), CC_CASH("到付现结");
        map.put("goodsType", JTExpressGoodsTypeEnum.getValue(goodsType));
        map.put("weight", weight);
        sender.put("name", StringUtils.isNotBlank(senderAddress.getRealName()) && !senderAddress.getRealName().equals(senderAddress.getName()) ? senderAddress.getRealName() + "(" + senderAddress.getName() + ")" : senderAddress.getRealName());
        sender.put("mobile", senderAddress.getMobile());
        sender.put("phone", senderAddress.getMobile());
        sender.put("countryCode", "CHN");
        sender.put("prov", senderAddress.getProvince());
        sender.put("city", senderAddress.getCity());
        sender.put("area", senderAddress.getArea());
        sender.put("address", senderAddress.getTown() + senderAddress.getAddress());
        map.put("sender", sender);
        receiver.put("name", receiverAddress.getName());
        receiver.put("mobile", receiverAddress.getMobile());
        receiver.put("phone", receiverAddress.getMobile());
        receiver.put("countryCode", "CHN");
        receiver.put("prov", receiverAddress.getProvince());
        receiver.put("city", receiverAddress.getCity());
        receiver.put("area", receiverAddress.getArea());
        receiver.put("address", receiverAddress.getTown() + receiverAddress.getAddress());
        map.put("receiver", receiver);
        try {
            com.alibaba.fastjson.JSONObject jsonObject = jtExpressApi.postByCustom(map, url);
            return jsonObject.toJSONString();
        } catch (IOException e) {
            e.printStackTrace();
            throw new CustomException("服务异常,请重试");
        }
    }

    @Override
    public JSONObject queryRoute(String senderAddress, String receiverAddress) {
        String url = "https://openapi.yundaex.com/openapi-api/v1/bm/queryRoute";
        JSONObject jsonParams = new JSONObject();
        JSONArray objects = new JSONArray(1);
        JSONObject jsonData = new JSONObject();
        jsonData.put("id", IdUtil.getSnowflakeNextIdStr());
        jsonData.put("sender_address", senderAddress);
        jsonData.put("receiver_address", receiverAddress);
        objects.add(jsonData);
        jsonParams.put("orders", objects);
        log.info("yunda check param {}", jsonParams);
        String response = OpenApiHttpUtils.doPostJson(url, jsonParams.toString(), yundaexConfig.getAppkey(), yundaexConfig.getAppSecret());
        log.info("yunda check res {}", response);
        return JSONObject.parseObject(response);
    }

    @Override
    public void logisticPackage(String mailNo, String productName, BigDecimal weight) {
        //http 工具类通用方法
        String serverUrl = "https://u-openapi.yundasys.com/openapi/outer/logictis/query";
        String sourceContent = "{\"mailno\":\"3120052228790\"}";
        System.out.println(OpenApiHttpUtils.doPostJson(serverUrl, sourceContent, yundaexConfig.getAppkey(), yundaexConfig.getAppSecret()));
    }

    @Override
    public Object check(LogisticCheck logisticCheckRequestVo) {
        Map<String, Object> checkMap = new HashMap<>(2);
        String deliveryId = logisticCheckRequestVo.getDeliveryId();
        LogisticCheckAddress senderAddress = logisticCheckRequestVo.getSenderAddress();
        LogisticCheckAddress receiverAddress = logisticCheckRequestVo.getReceiverAddress();
        if (DeliveryEnum.STO.toString().equals(deliveryId)) {
            final String url = "https://cloudinter-linkgateway.sto.cn/gateway/link.do";
            JSONObject content = new JSONObject();
            JSONObject sendAddress = new JSONObject();
            sendAddress.put("provinceName", senderAddress.getProvince());
            sendAddress.put("cityName", senderAddress.getCity());
            sendAddress.put("areaName", senderAddress.getArea());
            sendAddress.put("townName", senderAddress.getArea());
            sendAddress.put("detailAddress", senderAddress.getAddress());
            content.put("sendAddress", sendAddress);
            JSONObject consigneeAddress = new JSONObject();
            consigneeAddress.put("provinceName", receiverAddress.getProvince());
            consigneeAddress.put("cityName", receiverAddress.getCity());
            consigneeAddress.put("areaName", receiverAddress.getArea());
            consigneeAddress.put("townName", receiverAddress.getArea());
            consigneeAddress.put("detailAddress", receiverAddress.getAddress());
            content.put("consigneeAddress", consigneeAddress);
            JSONObject publicParam = new JSONObject();
            publicParam.put("api_name", "BLIND_SPOT_CHECK");
            publicParam.put("content", content.toString());
            publicParam.put("from_appkey", stoConfig.getAppKey());
            publicParam.put("from_code", stoConfig.getCode());
            publicParam.put("to_appkey", "ORDERMS_API");
            publicParam.put("to_code", "ORDERMS_API");
            publicParam.put("data_digest", getSignature(content.toString(), stoConfig.getSecretKey()));
            log.info("sto check param {}", publicParam);
            String res = HttpUtil.post(url, publicParam);
            log.info("sto check {}", res);
            JSONObject jsonObject = JSONObject.parseObject(res);
            if (jsonObject != null && jsonObject.getBoolean("success")) {
                JSONObject data = jsonObject.getJSONObject("data");
//                if (!data.getBoolean("isOutOfDelivery")){
//                    //末端可达预测接口
//                    platformSortationAddressOutOfDelivery(senderAddress, receiverAddress);
//                }
                checkMap.put("isOutOfDelivery", data.getBoolean("isOutOfDelivery"));
                checkMap.put("message", data.getString("message"));
            } else {
                throw new CustomException(jsonObject.getString("服务异常"));
            }
        }
        if (DeliveryEnum.YUNDA.toString().equals(deliveryId)) {
            String senderAddressDetail = senderAddress.getProvince() + senderAddress.getCity() + senderAddress.getArea() + senderAddress.getAddress();
            String receiverAddressDetail = receiverAddress.getProvince() + receiverAddress.getCity() + receiverAddress.getArea() + receiverAddress.getAddress();
            JSONObject jsonObject = this.queryRoute(senderAddressDetail, receiverAddressDetail);
            if (jsonObject != null && "0000".equals(jsonObject.getString("code"))) {
                JSONObject data = jsonObject.getJSONObject("data");
                JSONArray response = data.getJSONArray("response");
                for (int i = 0; i < response.size(); i++) {
                    JSONObject object = response.getJSONObject(i);
                    // 关停状态 ：0或1，0：不关停，1：关停
                    String close = object.getString("close");
                    if ("0".equals(close)) {
                        checkMap.put("isOutOfDelivery", false);
                        checkMap.put("message", null);
                    }
                    if ("1".equals(close)) {
                        checkMap.put("isOutOfDelivery", true);
                        checkMap.put("message", object.getString("close_reason_one"));
                    }
                }
            }
        }
        if (DeliveryEnum.EMS.toString().equals(deliveryId)) {
            Delivery delivery = deliveryService.getConfig(DeliveryEnum.EMS.toString());
            JSONObject body = new JSONObject();
            body.put("baseProductNo", "2");//1.特快专递  2.快递包裹 3.到付 9.即日 10.电商标快 11.标准快递
//            body.put("bizProductId", "");
            body.put("contentsAttribute", "3");// 内件性质 1：文件 3、物品
//            body.put("weight", "");
            body.put("receiverProv", receiverAddress.getProvince());
            body.put("receiverCity", receiverAddress.getCity());
            body.put("receiverCounty", receiverAddress.getArea());
            body.put("receiverAddress", receiverAddress.getAddress());
            body.put("senderProv", senderAddress.getProvince());
            body.put("senderCity", senderAddress.getCity());
            body.put("senderCounty", senderAddress.getArea());
            body.put("senderAddress", senderAddress.getAddress());
            String postData = EMSUtils.doPost("060002", delivery.getBizid(), delivery.getAuthCode(), body.toJSONString(), delivery.getPassword());
            if (StringUtils.isNotBlank(postData)) {
                JSONObject object = JSONObject.parseObject(postData);
                // 00000-表示成功S00001-表示系统级错误B00001-表示接口级错误
                if (object != null) {
                    if ("00000".equals(object.getString("retCode"))) {
                        checkMap.put("isOutOfDelivery", false);
                        checkMap.put("message", null);
                    } else {
                        checkMap.put("isOutOfDelivery", true);
                        checkMap.put("message", object.getString("retMsg"));
                    }
                }
            } else {
                throw new CustomException("查询异常");
            }
        }
        if (DeliveryEnum.JTSD.toString().equals(deliveryId)) {
            String url = "https://openapi.jtexpress.com.cn/webopenplatformapi/api/route/rangeCheck";
            Map<String, Object> map = new HashMap<>(8);
            map.put("senderProvName", senderAddress.getProvince());
            map.put("senderCityName", senderAddress.getCity());
            map.put("senderAreaName", senderAddress.getArea());
            map.put("receiverProvName", receiverAddress.getProvince());
            map.put("receiverCityName", receiverAddress.getCity());
            map.put("receiverAreaName", receiverAddress.getArea());
            map.put("receiverAddress", receiverAddress.getAddress());
            try {
                com.alibaba.fastjson.JSONObject jsonObject = jtExpressApi.postByCustom(map, url);
                log.info("jt range check -> {}", jsonObject);
                if (jsonObject == null) {
                    throw new CustomException("请重试");
                }
                if ("1".equals(jsonObject.getString("code"))) {
                    com.alibaba.fastjson.JSONObject data = jsonObject.getJSONObject("data");
                    String rangeCheckResult = data.getString("rangeCheckResult");
                    checkMap.put("isOutOfDelivery", !"1".equals(rangeCheckResult));
                    checkMap.put("message", data.getString("abnormalType") + data.getString("abnormalReason"));
                } else {
                    throw new CustomException(jsonObject.getString("msg"));
                }
            } catch (IOException e) {
                e.printStackTrace();
                log.error("jt range check err -> {}", e);
                throw new CustomException("服务异常");
            }
        }
        if (DeliveryEnum.SF.toString().equals(deliveryId)) {
            JSONObject data = new JSONObject();
            data.put("orderId", "EL" + IdUtil.getSnowflakeNextIdStr());
            List<JSONObject> contactInfoList = new ArrayList<>(2);
            JSONObject sender = new JSONObject();
            sender.put("contactType", 1);
            sender.put("mobile", senderAddress.getMobile());
            sender.put("province", senderAddress.getProvince());
            sender.put("city", senderAddress.getCity());
            sender.put("county", senderAddress.getArea());
            sender.put("address", senderAddress.getAddress());
            contactInfoList.add(sender);
            JSONObject receiver = new JSONObject();
            receiver.put("contactType", 2);
            receiver.put("mobile", receiverAddress.getMobile());
            receiver.put("province", receiverAddress.getProvince());
            receiver.put("city", receiverAddress.getCity());
            receiver.put("county", receiverAddress.getArea());
            receiver.put("address", receiverAddress.getAddress());
            contactInfoList.add(receiver);
            data.put("expressTypeId", logisticCheckRequestVo.getExpressType() == null ? 2 : logisticCheckRequestVo.getExpressType());
            data.put("contactInfoList", contactInfoList);
            try {
                String result = CallExpressSFHttpUtil.callSFApi("EXP_RECE_PRE_ORDER", data.toJSONString());
                JSONObject jsonObject = JSONObject.parseObject(result);
                if (!"A1000".equals(jsonObject.getString("apiResultCode"))) {
                    throw new CustomException(jsonObject.getString("apiErrorMsg"));
                }
                JSONObject apiResultData = jsonObject.getJSONObject("apiResultData");
                if (!apiResultData.getBoolean("success")) {
                    throw new CustomException(apiResultData.getString("errorMsg"));
                }
                JSONArray msgData = apiResultData.getJSONArray("msgData");
                checkMap.put("isOutOfDelivery", msgData.isEmpty());
                checkMap.put("message", null);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        if (DeliveryEnum.JD.toString().equals(deliveryId)) {
            try {
                Delivery config = deliveryService.getConfig(DeliveryEnum.JD.toString());
                EcapV1OrdersPrecheckLopRequest request = new EcapV1OrdersPrecheckLopRequest();
                CommonCreateOrderRequest commonCreateOrderRequest = new CommonCreateOrderRequest();
                Contact senderContact = new Contact();
                senderContact.setFullAddress(senderAddress.getProvince() + senderAddress.getCity() + senderAddress.getArea() + senderAddress.getAddress());
                Contact receiverContact = new Contact();
                receiverContact.setFullAddress(receiverAddress.getProvince() + receiverAddress.getCity() + receiverAddress.getArea() + receiverAddress.getAddress());
                commonCreateOrderRequest.setOrderOrigin(1);
                commonCreateOrderRequest.setCustomerCode("029K3587670");
                commonCreateOrderRequest.setSenderContact(senderContact);
                commonCreateOrderRequest.setReceiverContact(receiverContact);
                LopPlugin lopPlugin = OAuth2PluginFactory.produceLopPlugin(config.getBizid(), config.getPassword(), config.getAuthCode());
                request.setUseJosAuth(false);
                request.addLopPlugin(lopPlugin);
                request.setRequest(commonCreateOrderRequest);
                EcapV1OrdersPrecheckLopResponse response = defaultDomainApiClient.execute(request);
                if (response != null && response.getResult() != null) {
                    checkMap.put("isOutOfDelivery", !response.getResult().getSuccess());
                    checkMap.put("message", response.getResult().getMsg());
                }
                CommonCheckPreCreateOrderResponse data = response.getResult().getData();
                log.info("check pre data {}", data);
            } catch (LopException e) {
                e.printStackTrace();
                log.error("check pre err{}", e);
            }
        }
        return checkMap;
    }


    @Override
    public List<OrderProduct> createOrder(String orderId) {
        OrderVo order = orderService.getDetail(orderId);
        if (order.getPayStatus() == null || order.getPayStatus() == 0){
            throw new CustomException("此订单未完成付款");
        }
        List<OrderProduct> orderProductList = orderProductService.getOrderProductList(order.getId());
        List<OrderAddress> addressList = orderAddressService.getAddressList(orderId);
        OrderAddress senderAddress = addressList.stream().filter(orderAddress -> orderAddress.getType() == 1).findFirst().get();
        OrderAddress receiverAddress = addressList.stream().filter(orderAddress -> orderAddress.getType() == 2).findFirst().get();
        orderProductList = this.createOrder(orderId, orderProductList.get(0).getDeliveryId(), senderAddress, receiverAddress, orderProductList);
        if (order.getPayStatus() == 1 && order.getOrderType() == 1 ){
            String itemDesc = null;
            if (order.getOrderType() == 1){
                itemDesc = orderProductList.get(0).getItemType();
            }
            User user = userService.get(order.getPayerId());
            String appid = user.getAppid();
            String accessToken = wechatService.getAccessToken(appid, clientConfig.getAppid().equals(appid) ? clientConfig.getSecret() : manageConfig.getSecret());
            try {
                wechatService.uploadShippingInfo(order.getTransactionId(), orderProductList.get(0).getWaybillId(),
                        orderProductList.get(0).getDeliveryId(), itemDesc, order.getPayerId(), senderAddress.getMobile(), receiverAddress.getMobile(),1,  accessToken);
            } catch (Exception e) {
                e.printStackTrace();
            }
            order.setDeliveryStatus(1);
            orderService.update(order);
        }
        return orderProductList;
    }

    @Override
    public List<OrderProduct> createOrder(String orderId, String deliveryId, OrderAddress senderAddress, OrderAddress receiverAddress, List<OrderProduct> orderProducts) {
        Delivery config = deliveryService.getConfig(deliveryId);
        if (config == null){
            throw new CustomException("面单不存在");
        }
        this.realName(deliveryId, senderAddress.getRealName(), senderAddress.getRealId(), senderAddress.getMobile(), senderAddress.getProvince() + senderAddress.getCity() + senderAddress.getArea() + senderAddress.getTown() + senderAddress.getAddress());
        String goodsName = orderProducts.stream().map(product -> product.getItemType()).collect(Collectors.joining(","));
        String notes = orderProducts.stream().map(product -> product.getItemNotes()).collect(Collectors.joining(","));
        BigDecimal weight = orderProducts.stream().map(product -> new BigDecimal(StringUtils.isEmpty(product.getWeight()) ? "0" : product.getWeight())).reduce(BigDecimal::add).get();
        /*if (DeliveryEnum.STO.toString().equals(deliveryId)) {
            throw new CustomException("申通物流已停运,请使用其它物流");
        }
        if (DeliveryEnum.YUNDA.toString().equals(deliveryId)) {
            throw new CustomException("韵达物流已停运,请使用其它物流");
        }*/
        if (DeliveryEnum.STO.toString().equals(deliveryId)) {
            String res = buildExpressOrder(goodsName, weight.toPlainString(), senderAddress, receiverAddress, config);
            JSONObject jsonObject = JSONObject.parseObject(res);
            log.info("orderId {} data {}", orderId, jsonObject);
            if (jsonObject.getBoolean("success")) {
                JSONObject data = jsonObject.getJSONObject("data");
                String waybillNo = data.getString("waybillNo");
                String bw = data.getString("bigWord");
                    /*if (!bw.contains("-") || !bw.contains(" ") || bw.length() < 8){
                        this.cancelOrder(orderId, deliveryId, waybillNo);
                        throw new CustomException("获取面单异常,请重试");
                    }*/
                JSONArray array = new JSONArray();
                JSONObject bigWord = new JSONObject();
                bigWord.put("bigWord", bw);
                JSONObject packagePlace = new JSONObject();
                packagePlace.put("packagePlace", data.getString("packagePlace"));
                array.add(bigWord);
                array.add(packagePlace);
                for (OrderProduct orderProduct : orderProducts) {
                    orderProduct.setWaybillId(waybillNo);
                    orderProduct.setBigWord(bw);
                    orderProduct.setPackagePlace(data.getString("packagePlace"));
                    orderProduct.setWaybillData(array.toJSONString());
                    if (StringUtils.isBlank(orderProduct.getDeliveryName())){
                        orderProduct.setDeliveryName(config.getDeliveryName());
                    }
                    orderProduct.setOrderSerialNo(data.getString("orderNo"));
                    orderProduct.setRemark(data.toJSONString());
                    orderProduct.setUpdateTime(new Date());
                    orderProductService.update(orderProduct);
                }
            } else {
                throw new CustomException(jsonObject.getString("errorMsg"));
            }
        }
        if (DeliveryEnum.YUNDA.toString().equals(deliveryId)) {
            String response = this.createBmOrder(senderAddress, receiverAddress, weight, goodsName, notes);
            log.info("yunda orderId {} create bm order res {}", orderId, response);
            JSONObject jsonObject = JSONObject.parseObject(response);
            if (jsonObject == null) {
                throw new CustomException("获取失败");
            }
            if ("0000".equals(jsonObject.getString("code"))) {
                JSONArray dataList = jsonObject.getJSONArray("data");
                for (int i = 0; i < dataList.size(); i++) {
                    JSONObject data = dataList.getJSONObject(i);
                    if ("1".equals(data.getString("status"))) {
                        String pdfInfo = data.getString("pdf_info");
                        JSONArray pdfArray = JSONArray.parseArray(pdfInfo);
                        String pdfArrayOne = pdfArray.getString(0);
                        JSONArray jsonArray = JSONObject.parseObject(pdfArrayOne, JSONArray.class);
                        String jsonData = jsonArray.getString(0);
                        YunDaPdf pdf = JSONObject.parseObject(jsonData, YunDaPdf.class);
                        String position = pdf.getPosition();
                        String positionNo = pdf.getPositionNo();
                        String packageWdjc = pdf.getPackageWdjc();
                        JSONArray array = new JSONArray();
                        JSONObject packagePlace = new JSONObject();
                        JSONObject bigWord = new JSONObject();
                        packagePlace.put("packagePlace", packageWdjc);
                        bigWord.put("bigWord", position + " " + positionNo);
                        array.add(packagePlace);
                        array.add(bigWord);
                        String mailno = data.getString("mailno") == null ? data.getString("mail_no") : data.getString("mailno");
                        if (StringUtils.isBlank(mailno)) {
                            mailno = pdf.getMailno();
                        }
                        if (StringUtils.isBlank(mailno)) {
                            this.cancelOrder(orderId, deliveryId, mailno);
                            throw new CustomException("获取面单异常,请重试");
                        }
//                        if (StringUtils.isBlank(positionNo)) {
//                            this.cancelOrder(orderId, deliveryId, mailno);
//                            throw new CustomException("地址有误，请检查地址");
//                        }
                        String subscribe = this.logisticSubscribe(deliveryId, senderAddress, receiverAddress, data.getString("order_serial_no"), mailno);
                        log.info("order subscribe result {}", subscribe);
                        for (OrderProduct product : orderProducts) {
                            product.setRemark(JSONObject.toJSONString(pdf));
                            product.setOrderSerialNo(data.getString("order_serial_no"));
                            product.setWaybillId(mailno);
                            product.setBigWord(position + " " + pdf.getPositionNo());
                            product.setPackagePlace(packageWdjc);
                            product.setWaybillData(array.toJSONString());
                            product.setUpdateTime(new Date());
                            if (StringUtils.isNotBlank(subscribe)) {
                                product.setSubcribeResult(subscribe);
                            }
                            if (StringUtils.isBlank(product.getDeliveryName())){
                                product.setDeliveryName(config.getDeliveryName());
                            }
                            orderProductService.update(product);
                        }
                    } else {
                        throw new CustomException(data.getString("msg"));
                    }
                }
            } else {
                throw new CustomException(jsonObject.getString("message"));
            }
        }
        if (DeliveryEnum.EMS.toString().equals(deliveryId)) {
            String emsOrder = this.createEMSOrder(senderAddress, receiverAddress, goodsName, goodsName);
            log.info("ems order {}, {}", orderId, emsOrder);
            if (StringUtils.isNotBlank(emsOrder)) {
                JSONObject jsonObject = JSONObject.parseObject(emsOrder);
                if ("00000".equals(jsonObject.getString("retCode"))) {
                    JSONObject retBody = jsonObject.getJSONObject("retBody");
                    for (OrderProduct product : orderProducts) {
                        if (StringUtils.isBlank(product.getDeliveryName())){
                            product.setDeliveryName(config.getDeliveryName());
                        }
                        product.setOrderSerialNo(retBody.getString("logisticsOrderNo"));
                        product.setWaybillId(retBody.getString("waybillNo"));
                        product.setBigWord(retBody.getString("routeCode"));
                        product.setPackagePlace(retBody.getString("packageCodeName"));
                        product.setWaybillData(retBody.getString("routeCode"));
                        product.setRemark(retBody.toJSONString());
                        product.setUpdateTime(new Date());
                        orderProductService.update(product);
                    }
                } else {
                    throw new CustomException(jsonObject.getString("retMsg"));
                }
            }
        }
        if (DeliveryEnum.JTSD.toString().equals(deliveryId)) {
            String result = this.createJTOrder(senderAddress, receiverAddress, orderProducts.get(0).getId(), orderProducts.get(0).getItemType(), weight.toPlainString());
            log.info("jt order {} ,  -> {}", orderId, result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            if (jsonObject != null) {
                if ("1".equals(jsonObject.getString("code"))) {
                    JSONObject data = jsonObject.getJSONObject("data");
                    String billCode = data.getString("billCode");
                    JSONArray array = new JSONArray();
                    JSONObject packagePlace = new JSONObject();
                    JSONObject bigWord = new JSONObject();
                    packagePlace.put("packagePlace", data.getString("lastCenterName"));
                    bigWord.put("bigWord", data.getString("sortingCode"));
                    array.add(packagePlace);
                    array.add(bigWord);
                    for (OrderProduct product : orderProducts) {
                        if (StringUtils.isBlank(product.getDeliveryName())){
                            product.setDeliveryName(config.getDeliveryName());
                        }
                        product.setOrderSerialNo(data.getString("txlogisticId"));
                        product.setWaybillId(billCode);
                        product.setBigWord(data.getString("sortingCode"));
                        product.setPackagePlace(data.getString("lastCenterName"));
                        product.setWaybillData(array.toJSONString());
                        product.setRemark(data.toJSONString());
                        product.setUpdateTime(new Date());
                        orderProductService.update(product);
                    }
                } else {
                    throw new CustomException(jsonObject.getString("msg"));
                }
            } else {
                throw new CustomException("下单失败,请重试");
            }
        }
        if (DeliveryEnum.SF.toString().equals(deliveryId)) {
            JSONObject data = new JSONObject();
            data.put("language", "zh-CN");
            String expressOrderId = IdUtil.getSnowflakeNextIdStr();
            data.put("orderId", "ELE" + expressOrderId);
            JSONArray contactInfoList = new JSONArray();
            JSONObject sender = new JSONObject();
            sender.put("contactType", 1);// 1，寄件方信息 2，到件方信息
            sender.put("contact", StringUtils.isNotBlank(senderAddress.getRealName()) && !senderAddress.getRealName().equals(senderAddress.getName()) ? senderAddress.getRealName() + "(" + senderAddress.getName() + ")" : senderAddress.getRealName());

            sender.put("mobile", senderAddress.getMobile());
            sender.put("province", senderAddress.getProvince());
            sender.put("city", senderAddress.getCity());
            sender.put("county", senderAddress.getArea());
            sender.put("address", senderAddress.getTown() + senderAddress.getAddress());
            contactInfoList.add(sender);
            JSONObject receiver = new JSONObject();
            receiver.put("contactType", 2);
            receiver.put("contact", receiverAddress.getName());
            receiver.put("mobile", receiverAddress.getMobile());
            receiver.put("province", receiverAddress.getProvince());
            receiver.put("city", receiverAddress.getCity());
            receiver.put("county", receiverAddress.getArea());
            receiver.put("address", receiverAddress.getTown() + receiverAddress.getAddress());
            contactInfoList.add(receiver);
            data.put("contactInfoList", contactInfoList);
            data.put("monthlyCard", config.getAuthCode());
            data.put("totalWeight", weight.setScale(3, RoundingMode.HALF_UP));
            JSONArray cargoDetails = new JSONArray();
            JSONObject cargoDetail = new JSONObject();
            cargoDetail.put("name", goodsName);
            cargoDetail.put("weight", weight.setScale(3, RoundingMode.HALF_UP));
            cargoDetails.add(cargoDetail);
            data.put("cargoDetails", cargoDetails);
            data.put("expressTypeId", orderProducts.get(0).getExpressType() == null ? 2 : orderProducts.get(0).getExpressType());
            try {
                log.info("sf order param {}", data);
                String result = CallExpressSFHttpUtil.callSFApi("EXP_RECE_CREATE_ORDER", data.toJSONString());
                log.info("sf order res {}", result);
                JSONObject jsonObject = JSONObject.parseObject(result);
                if (!"A1000".equals(jsonObject.getString("apiResultCode"))) {
                    throw new CustomException(jsonObject.getString("apiErrorMsg"));
                }
                JSONObject apiResultData = jsonObject.getJSONObject("apiResultData");
                if (!apiResultData.getBoolean("success")) {
                    throw new CustomException(apiResultData.getString("errorMsg"));
                }
                JSONObject msgData = apiResultData.getJSONObject("msgData");
                if (msgData == null || msgData.isEmpty()) {
                    msgData = sfExpressQuerOrderResp(expressOrderId, null);
                }
                JSONArray waybillNoInfoList = msgData.getJSONArray("waybillNoInfoList");
                JSONArray routeLabelInfo = msgData.getJSONArray("routeLabelInfo");
                for (int i = 0; i < waybillNoInfoList.size(); i++) {
                    JSONObject jsonObject1 = waybillNoInfoList.getJSONObject(i);
                    String waybillNo = jsonObject1.getString("waybillNo");

                    for (int j = 0; j < routeLabelInfo.size(); j++) {
                        JSONObject jsonObject2 = routeLabelInfo.getJSONObject(j);
                        JSONObject routeLabelData = jsonObject2.getJSONObject("routeLabelData");
                        if (routeLabelData != null && routeLabelData.getString("waybillNo").equals(waybillNo)) {

                            JSONArray array = new JSONArray();
                            JSONObject packagePlace = new JSONObject();
                            JSONObject bigWord = new JSONObject();
                            packagePlace.put("packagePlace", routeLabelData.getString("destTransferCode"));
                            bigWord.put("bigWord", routeLabelData.getString("destRouteLabel"));
                            array.add(packagePlace);
                            array.add(bigWord);
                            for (OrderProduct product : orderProducts) {
                                if (StringUtils.isBlank(product.getDeliveryName())){
                                    product.setDeliveryName(config.getDeliveryName());
                                }
                                product.setOrderSerialNo(msgData.getString("orderId"));
                                product.setWaybillId(waybillNo);
                                product.setBigWord(routeLabelData.getString("destRouteLabel"));
                                product.setPackagePlace(routeLabelData.getString("destTransferCode"));
                                product.setWaybillData(array.toJSONString());
                                product.setRemark(data.toJSONString());
                                product.setUpdateTime(new Date());
                                orderProductService.update(product);
                            }
                        }
                    }
                }
                // 订单结果查询
            } catch (Exception e) {
                e.printStackTrace();
                this.cancelOrder(orderId, deliveryId, null);
                throw new CustomException("下单失败，请重试");
            }
        }
        if (DeliveryEnum.JD.toString().equals(deliveryId)) {
            try {
                EcapV1OrdersCreateLopRequest request = new EcapV1OrdersCreateLopRequest();
                com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCreateOrderV1.CommonCreateOrderRequest commonCreateOrderRequest = new com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCreateOrderV1.CommonCreateOrderRequest();
                com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCreateOrderV1.Contact senderContact = new com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCreateOrderV1.Contact();
                senderContact.setName(StringUtils.isNotBlank(senderAddress.getRealName()) && !senderAddress.getRealName().equals(senderAddress.getName()) ? senderAddress.getRealName() + "(" + senderAddress.getName() + ")" : senderAddress.getRealName());

                senderContact.setCompany(senderAddress.getCompany());
                senderContact.setPhone(senderAddress.getMobile());
                senderContact.setFullAddress(senderAddress.getProvince() + senderAddress.getCity() + senderAddress.getArea() + senderAddress.getTown() + senderAddress.getAddress());
                com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCreateOrderV1.Contact receiverContact = new com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCreateOrderV1.Contact();
                receiverContact.setName(receiverAddress.getName());
                receiverContact.setCompany(receiverAddress.getCompany());
                receiverContact.setPhone(receiverAddress.getMobile());
                receiverContact.setFullAddress(receiverAddress.getProvince() + receiverAddress.getCity() + receiverAddress.getArea() + receiverAddress.getTown() + receiverAddress.getAddress());
                commonCreateOrderRequest.setSenderContact(senderContact);
                commonCreateOrderRequest.setReceiverContact(receiverContact);
                com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCreateOrderV1.CommonProductInfo commonProductInfo = new com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCreateOrderV1.CommonProductInfo();
                commonProductInfo.setProductCode("1".equals(orderProducts.get(0).getExpressType()) ? "ed-m-0001" : "ed-m-0059");// 标快ed-m-0001 // 特快 ed-m-0002
                commonCreateOrderRequest.setProductsReq(commonProductInfo);
                commonCreateOrderRequest.setOrderId("ELE_" + IdUtil.getSnowflakeNextIdStr());
                commonCreateOrderRequest.setSettleType(3);
                commonCreateOrderRequest.setCustomerCode("029K3587670");
                commonCreateOrderRequest.setOrderOrigin(1);
                java.util.List<com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCreateOrderV1.CommonCargoInfo> cargoInfoList = new java.util.ArrayList();
                com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCreateOrderV1.CommonCargoInfo cargoInfo = new com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCreateOrderV1.CommonCargoInfo();
                cargoInfo.setName(goodsName);
                cargoInfo.setQuantity(1);
                cargoInfo.setWeight(weight.setScale(2, RoundingMode.HALF_UP));
                cargoInfo.setVolume(new BigDecimal("3000"));
                cargoInfoList.add(cargoInfo);
                commonCreateOrderRequest.setCargoes(cargoInfoList);
                commonCreateOrderRequest.setPickupType(1);
                LopPlugin lopPlugin = OAuth2PluginFactory.produceLopPlugin(config.getBizid(), config.getPassword(), config.getAuthCode());
                request.setUseJosAuth(false);
                request.addLopPlugin(lopPlugin);
                request.setRequest(commonCreateOrderRequest);
                EcapV1OrdersCreateLopResponse response = defaultDomainApiClient.execute(request);
                if (response != null && response.getResult() != null && response.getResult().getSuccess()) {
                    CommonCreateOrderResponse data = response.getResult().getData();
                    log.info("jd create order data {}", data);
                    String waybillCode = data.getWaybillCode();
                    FaceSheetResponse<FaceSheetInfo> faceSheetResponse = data.getFaceSheetResponse();
                    FaceSheetInfo faceSheetInfo = faceSheetResponse.getFaceSheetInfo();
                    String collectionAddress = faceSheetInfo.getCollectionAddress();
                    if (StringUtils.isBlank(collectionAddress)) {
                        collectionAddress = faceSheetInfo.getStartSiteName() + "_" + faceSheetInfo.getEndSiteName();
                    }
                    JSONArray array = new JSONArray();
                    JSONObject packagePlace = new JSONObject();
                    JSONObject bigWord = new JSONObject();
                    packagePlace.put("packagePlace", collectionAddress);
                    bigWord.put("bigWord", waybillCode);
                    array.add(packagePlace);
                    array.add(bigWord);
                    String subscribe = this.logisticSubscribe(deliveryId, senderAddress, receiverAddress, null, waybillCode);
                    for (OrderProduct product : orderProducts) {
                        if (StringUtils.isBlank(product.getDeliveryName())){
                            product.setDeliveryName(config.getDeliveryName());
                        }
                        product.setBigWord(waybillCode);
                        product.setPackagePlace(collectionAddress);
                        product.setWaybillId(waybillCode);
                        product.setWaybillData(array.toJSONString());
                        product.setOrderSerialNo(commonCreateOrderRequest.getOrderId());
                        product.setRemark(JSONObject.toJSONString(data));
                        product.setSubcribeResult(subscribe);
                        product.setUpdateTime(new Date());
                        orderProductService.update(product);
                    }
                } else {
                    throw new CustomException(response.getResult().getSubMsg());
                }
            } catch (LopException e) {
                e.printStackTrace();
                log.error("check pre err{}", e);
            }
        }
        return orderProducts;
    }

    @Override
    public List<OrderLogisticStep> queryLogistic(String orderId, String deliveryId, String waybillId, String appId, String secret, String userId) {
        if (DeliveryEnum.STO.toString().equals(deliveryId)) {
            String str = buildSTOTraceQuery(waybillId);
            log.info("sto logistic res {}", str);
            JSONObject jsonObject = JSONObject.parseObject(str);
            if (jsonObject.getBoolean("success")) {
                JSONObject data = jsonObject.getJSONObject("data");
                JSONArray waybillNoArray = data.getJSONArray(waybillId);
                List<OrderLogisticStep> orderLogisticStepList = new ArrayList<>(waybillNoArray.size());
                for (int i = 0; i < waybillNoArray.size(); i++) {
                    JSONObject waybillObj = waybillNoArray.getJSONObject(i);
                    log.info("info {}", waybillObj);
                    OrderLogisticStep orderLogisticStep = new OrderLogisticStep();
                    orderLogisticStep.setNextCity(waybillObj.getString("nextOrgName"));
                    orderLogisticStep.setSigner(waybillObj.getString("signoffPeople"));
                    orderLogisticStep.setCarNo(waybillObj.getString("carNo"));
                    orderLogisticStep.setDescription(waybillObj.getString("memo"));
                    orderLogisticStep.setPhone(waybillObj.getString("bizEmpPhone"));
                    orderLogisticStep.setName(waybillObj.getString("bizEmpName"));
                    orderLogisticStep.setCity(waybillObj.getString("opOrgCityName"));
                    orderLogisticStep.setProvince(waybillObj.getString("opOrgProvinceName"));
                    orderLogisticStep.setStationName(waybillObj.getString("opOrgName"));
                    orderLogisticStep.setTime(waybillObj.getString("opTime"));
                    orderLogisticStepList.add(orderLogisticStep);
                }
                return orderLogisticStepList;
            } else {
                throw new CustomException(jsonObject.getString("errorMsg"));
            }
        }
        if (DeliveryEnum.YUNDA.toString().equals(deliveryId)) {
            try {
                Long.parseLong(orderId);
            } catch (NumberFormatException e) {
                e.printStackTrace();
                log.warn("try subscribe yunda {}", orderId);
                this.subscribeOrder(orderId, userId);
            }
            /*String url = "https://api.weixin.qq.com/cgi-bin/express/business/path/get?access_token=" + wechatService.getAccessToken(appId, secret);
            JSONObject body = new JSONObject();
            body.put("openid", userId);
            body.put("delivery_id", DeliveryEnum.YUNDA.toString());
            body.put("waybill_id", waybillId);
            byte[] bytes = WechatHttpUtil.doWechatPost(url, body);
            try {
                JSONObject jsonObject = JSONObject.parseObject(new String(bytes, "utf-8"));
                JSONArray pathItemList = jsonObject.getJSONArray("path_item_list");
                List<OrderLogisticStep> orderLogisticStepList = new ArrayList<>(pathItemList.size());
                for (int i = 0; i < pathItemList.size(); i++) {
                    JSONObject pathItem = pathItemList.getJSONObject(i);
                    log.info(" yunda logistic {}", pathItem);
                    OrderLogisticStep orderLogisticStep = new OrderLogisticStep();
                    orderLogisticStep.setTime(DateUtil.format(pathItem.getDate("action_time"), "yyyy-MM-dd HH:mm:ss"));
                    orderLogisticStep.setStationType(pathItem.getString("action_type"));
                    orderLogisticStep.setDescription(pathItem.getString("action_msg"));
                    orderLogisticStepList.add(orderLogisticStep);
                }
                return orderLogisticStepList;
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                throw new CustomException("查询失败");
            }*/
            String str = yundaLogisicQuery(waybillId);
            log.info("yunda logistic res {}", str);
            JSONObject jsonObject = JSONObject.parseObject(str);
            if ("0000".equals(jsonObject.getString("code")) && jsonObject.getBoolean("result")) {
                JSONObject data = jsonObject.getJSONObject("data");
                if (data.getBoolean("result")) {
                    JSONArray steps = data.getJSONArray("steps");
                    List<OrderLogisticStep> orderLogisticStepList = new ArrayList<>(steps.size());
                    for (int i = 0; i < steps.size(); i++) {
                        JSONObject step = steps.getJSONObject(i);
                        log.info(" yunda logistic {}", step);
                        OrderLogisticStep orderLogisticStep = new OrderLogisticStep();
                        orderLogisticStep.setTime(DateUtil.format(step.getDate("time"), "yyyy-MM-dd HH:mm:ss"));
                        orderLogisticStep.setStatus(YunDaLogisticStatusEnum.getStatus(step.getString("status")));
                        orderLogisticStep.setAction(YunDaLogisticActionEnum.getAction(step.getString("action")));
                        orderLogisticStep.setCity(step.getString("city"));
                        orderLogisticStep.setNextCity(step.getString("next_city"));
                        orderLogisticStep.setStationName(step.getString("stationName"));
                        orderLogisticStep.setStationType(step.getString("station_type"));//轨迹发生站点类型1是网点，2是分拨中心
                        orderLogisticStep.setNextCity(step.getString("next_name"));
                        orderLogisticStep.setNextType(step.getString("next_type"));//下级站点类型 1是网点，2是分拨中心
                        orderLogisticStep.setDescription(step.getString("description"));
                        orderLogisticStep.setPhone(step.getString("phone"));
                        orderLogisticStep.setSigner(step.getString("signer"));
                        orderLogisticStepList.add(orderLogisticStep);
                    }
                    return orderLogisticStepList;
                } else {
                    throw new CustomException("查询失败");
                }
            } else {
                throw new CustomException(jsonObject.getString("message"));
            }
        }
        if (DeliveryEnum.EMS.toString().equals(deliveryId)) {
            Delivery delivery = deliveryService.getConfig(DeliveryEnum.EMS.toString());
            JSONObject body = new JSONObject();
            body.put("waybillNo", waybillId);
            String testData = EMSUtils.doPost("040001", "1100192693978", "SPJrowKnLy3agPWf", body.toJSONString(), "NGpRNFhNSmxod200M0l1bA==");
            String data = null;
            if (StringUtils.isNotBlank(testData)) {
                JSONObject jsonObject = JSONObject.parseObject(testData);
                if ("00000".equals(jsonObject.getString("retCode"))) {
                    data = testData;
                }
            }
            if (data == null) {
                data = EMSUtils.doPost("040001", delivery.getBizid(), delivery.getAuthCode(), body.toJSONString(), delivery.getPassword());
            }
            log.info("ems logistic data :", data);
            if (StringUtils.isNotBlank(data)) {
                JSONObject jsonObject = JSONObject.parseObject(data);
                if ("00000".equals(jsonObject.getString("retCode"))) {
                    JSONObject retBody = jsonObject.getJSONObject("retBody");
                    JSONArray responseItems = retBody.getJSONArray("responseItems");
                    List<OrderLogisticStep> orderLogisticStepList = new ArrayList<>(responseItems.size());
                    for (int i = 0; i < responseItems.size(); i++) {
                        JSONObject waybillObj = responseItems.getJSONObject(i);
                        OrderLogisticStep orderLogisticStep = new OrderLogisticStep();
                        log.info("ems logistic {}", waybillId);
                        orderLogisticStep.setDescription(waybillObj.getString("opDesc"));
                        orderLogisticStep.setCity(waybillObj.getString("opOrgCity"));
                        orderLogisticStep.setProvince(waybillObj.getString("opOrgProvName"));
                        orderLogisticStep.setStationName(waybillObj.getString("opOrgName"));
                        orderLogisticStep.setTime(waybillObj.getString("opTime"));
                        orderLogisticStepList.add(orderLogisticStep);
                    }
                    return orderLogisticStepList;
                } else {
                    throw new CustomException(jsonObject.getString("retMsg"));
                }
            } else {
                throw new CustomException("取消失败");
            }
        }
        if (DeliveryEnum.JTSD.toString().equals(deliveryId)) {
            Map<String, Object> map = new HashMap<>();
            map.put("billCodes", waybillId);
            try {
                com.alibaba.fastjson.JSONObject result = jtExpressApi.post(map, "https://openapi.jtexpress.com.cn/webopenplatformapi/api/logistics/trace");
                log.info("jt express query {}", result);
                if (result != null) {
                    if (result.getInteger("code") != 1) {
                        throw new CustomException(result.getString("msg"));
                    }
                    com.alibaba.fastjson.JSONArray data = result.getJSONArray("data");
                    for (int i = 0; i < data.size(); i++) {
                        com.alibaba.fastjson.JSONObject jsonObject = data.getJSONObject(i);
                        if (waybillId.equals(jsonObject.getString("billCode"))) {
                            com.alibaba.fastjson.JSONArray details = jsonObject.getJSONArray("details");
                            List<OrderLogisticStep> orderLogisticStepList = new ArrayList<>(details.size());
                            for (int j = 0; j < details.size(); j++) {
                                com.alibaba.fastjson.JSONObject detail = details.getJSONObject(j);
                                OrderLogisticStep orderLogisticStep = new OrderLogisticStep();
                                log.info("ems logistic {}", waybillId);
                                orderLogisticStep.setDescription(detail.getString("desc"));
                                orderLogisticStep.setCity(detail.getString("opOrgCity"));
                                orderLogisticStep.setProvince(detail.getString("scanNetworkProvince"));
                                orderLogisticStep.setCity(detail.getString("scanNetworkCity"));
                                orderLogisticStep.setStationName(detail.getString("scanNetworkName"));
                                orderLogisticStep.setTime(detail.getString("scanTime"));
                                orderLogisticStep.setPhone(detail.getString("staffContact"));
                                orderLogisticStep.setName(detail.getString("staffName"));
                                orderLogisticStep.setTime(detail.getString("scanTime"));
                                orderLogisticStepList.add(orderLogisticStep);
                            }
                            Collections.reverse(orderLogisticStepList);
                            return orderLogisticStepList;
                        }
                    }
                } else {
                    throw new CustomException("查询异常");
                }
            } catch (IOException e) {
                e.printStackTrace();
                log.error("err -> {}", e);
                throw new CustomException("查询异常");
            }
        }
        if (DeliveryEnum.SF.toString().equals(deliveryId)) {
            JSONObject body = new JSONObject();
            body.put("language", "zh-CN");
            body.put("trackingType", 1);
            JSONArray array = new JSONArray();
            array.add(waybillId);
            body.put("trackingNumber", array);
            body.put("methodType", 1);
            try {
                String result = CallExpressSFHttpUtil.callSFApi("EXP_RECE_SEARCH_ROUTES", body.toJSONString());
                if (StringUtils.isNotBlank(result)) {
                    JSONObject jsonObject = JSONObject.parseObject(result);
                    if (!"A1000".equals(jsonObject.getString("apiResultCode"))) {
                        throw new CustomException(jsonObject.getString("apiErrorMsg"));
                    }
                    JSONObject apiResultData = jsonObject.getJSONObject("apiResultData");
                    if (!apiResultData.getBoolean("success")) {
                        throw new CustomException(apiResultData.getString("errorMsg"));
                    }
                    JSONObject msgData = apiResultData.getJSONObject("msgData");
                    log.info("sf query route {}", msgData);
                    JSONArray routeResps = msgData.getJSONArray("routeResps");
                    List<OrderLogisticStep> orderLogisticStepList = new ArrayList<>();
                    for (int i = 0; i < routeResps.size(); i++) {
                        JSONObject route = routeResps.getJSONObject(i);
                        String mailNo = route.getString("mailNo");
                        JSONArray routes = route.getJSONArray("routes");
                        if (mailNo.equals(waybillId)) {
                            for (int j = 0; j < routes.size(); j++) {
                                JSONObject detail = routes.getJSONObject(j);
                                OrderLogisticStep orderLogisticStep = new OrderLogisticStep();
                                log.info("sf logistic {}", detail);
                                orderLogisticStep.setDescription(detail.getString("remark"));
                                orderLogisticStep.setStationName(detail.getString("acceptAddress"));
                                orderLogisticStep.setTime(detail.getString("acceptTime"));
                                orderLogisticStepList.add(orderLogisticStep);
                            }
                        }
                    }
                    return orderLogisticStepList;
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        if (DeliveryEnum.JD.toString().equals(deliveryId)) {
            try {
                Delivery config = deliveryService.getConfig(DeliveryEnum.JD.toString());
                List<OrderProduct> orderProductList = orderProductService.getOrderProductList(orderId);
                OrderProduct orderProduct = orderProductList.get(0);
                EcapV1OrdersTraceQueryLopRequest request = new EcapV1OrdersTraceQueryLopRequest();
                com.lop.open.api.sdk.domain.ECAP.CommonQueryOrderApi.commonGetOrderTraceV1.CommonOrderTraceRequest commonOrderTraceRequest = new com.lop.open.api.sdk.domain.ECAP.CommonQueryOrderApi.commonGetOrderTraceV1.CommonOrderTraceRequest();
                commonOrderTraceRequest.setWaybillCode(orderProduct.getWaybillId());
                commonOrderTraceRequest.setOrderOrigin(1);
                commonOrderTraceRequest.setCustomerCode("029K3587670");
                request.setCommonOrderTraceRequest(commonOrderTraceRequest);
                LopPlugin lopPlugin = OAuth2PluginFactory.produceLopPlugin(config.getBizid(), config.getPassword(), config.getAuthCode());
                request.setUseJosAuth(false);
                request.addLopPlugin(lopPlugin);
                EcapV1OrdersTraceQueryLopResponse response = defaultDomainApiClient.execute(request);
                if (response != null && response.getResult() != null) {
                    CommonOrderTraceResponse data = response.getResult().getData();
                    log.info("jd trace query data {}", JSONObject.toJSONString(data));
                    List<CommonOrderTraceDetail> traceDetails = data.getTraceDetails();
                    List<OrderLogisticStep> orderLogisticStepList = new ArrayList<>(traceDetails.size());
                    for (CommonOrderTraceDetail traceDetail : traceDetails) {
                        OrderLogisticStep orderLogisticStep = new OrderLogisticStep();
                        orderLogisticStep.setDescription(traceDetail.getOperationRemark());
                        orderLogisticStep.setStationName(traceDetail.getOperationTitle());
                        orderLogisticStep.setTime(traceDetail.getOperationTime());
                        orderLogisticStep.setName(traceDetail.getOperatorName());
                        orderLogisticStep.setStatus(traceDetail.getState());
                        orderLogisticStepList.add(orderLogisticStep);
                    }
                    return orderLogisticStepList;
                }
            } catch (LopException e) {
                e.printStackTrace();
                log.error("cancel order err{}", e);
            }
        }
        return null;
    }

    @Override
    public Boolean cancelOrder(String orderId, String deliveryId, String waybillId) {
        if (DeliveryEnum.STO.toString().equals(deliveryId)) {
            String str = buildSTOOrderCancel(waybillId);
            log.info("sto cancel order res {}", str);
            JSONObject jsonObject = JSONObject.parseObject(str);
            if (jsonObject.getBoolean("success")) {
                return true;
            } else {
                throw new CustomException(jsonObject.getString("errorMsg"));
            }
        }
        if (DeliveryEnum.YUNDA.toString().equals(deliveryId)) {
            Delivery delivery = deliveryService.getConfig(DeliveryEnum.YUNDA.toString());
            String str = yundaCancelBmOrder(delivery.getBizid(), delivery.getPassword(), waybillId);
            log.info("yunda cancel bm res {}", str);
            JSONObject jsonObject = JSONObject.parseObject(str);
            if ("0000".equals(jsonObject.getString("code")) && jsonObject.getBoolean("result")) {
                JSONArray data = jsonObject.getJSONArray("data");
                for (int i = 0; i < data.size(); i++) {
                    JSONObject object = data.getJSONObject(i);
                    if ("1".equalsIgnoreCase(object.getString("status"))) {
                        return true;
                    } else {
                        throw new CustomException(object.getString("msg").replace(waybillId, ""));
                    }
                }
            }
        }
        if (DeliveryEnum.EMS.toString().equals(deliveryId)) {
            Delivery delivery = deliveryService.getConfig(DeliveryEnum.EMS.toString());
            List<OrderProduct> orderProductList = orderProductService.getOrderProductList(orderId);
            for (OrderProduct product : orderProductList) {
                JSONObject body = new JSONObject();
                body.put("logisticsOrderNo", product.getOrderSerialNo());
                body.put("cancelReason", "取消");
                body.put("waybillNo", waybillId);
                String data = EMSUtils.doPost("020006", delivery.getBizid(), delivery.getAuthCode(), body.toJSONString(), delivery.getPassword());
                log.info("cancel ems data :", data);
                if (StringUtils.isNotBlank(data)) {
                    JSONObject jsonObject = JSONObject.parseObject(data);
                    if ("00000".equals(jsonObject.getString("retCode"))) {
                        return true;
                    } else {
                        throw new CustomException(jsonObject.getString("retMsg"));
                    }
                } else {
                    throw new CustomException("取消失败");
                }
            }
        }
        if (DeliveryEnum.JTSD.toString().equals(deliveryId)) {
            Delivery config = deliveryService.getConfig(DeliveryEnum.JTSD.toString());
            String url = "https://openapi.jtexpress.com.cn/webopenplatformapi/api/order/cancelOrder";
            Map<String, Object> map = new HashMap<>();
            map.put("txlogisticId", orderId);
            map.put("customerCode", config.getBizid());
            map.put("reason", "取消");
            try {
                com.alibaba.fastjson.JSONObject jsonObject = jtExpressApi.postByCustom(map, url);
                log.info("jt cancel -> {}", jsonObject);
                if (jsonObject == null) {
                    throw new CustomException("请重试");
                }
                if ("1".equals(jsonObject.getString("code"))) {
                    return true;
                } else {
                    throw new CustomException(jsonObject.getString("msg"));
                }
            } catch (IOException e) {
                e.printStackTrace();
                log.error("jt cancel err -> {}", e);
                throw new CustomException("服务异常");
            }
        }
        if (DeliveryEnum.SF.toString().equals(deliveryId)) {
            List<OrderProduct> orderProductList = orderProductService.getOrderProductList(orderId);
            String orderSerialNo = orderProductList.get(0).getOrderSerialNo();
            JSONObject body = new JSONObject();
            body.put("orderId", orderSerialNo);
            body.put("dealType", 2);
            try {
                String result = CallExpressSFHttpUtil.callSFApi("EXP_RECE_UPDATE_ORDER", body.toJSONString());
                if (StringUtils.isNotBlank(result)) {
                    JSONObject jsonObject = JSONObject.parseObject(result);
                    if (!"A1000".equals(jsonObject.getString("apiResultCode"))) {
                        throw new CustomException(jsonObject.getString("apiErrorMsg"));
                    }
                    JSONObject apiResultData = jsonObject.getJSONObject("apiResultData");
                    if (!apiResultData.getBoolean("success")) {
                        throw new CustomException(apiResultData.getString("errorMsg"));
                    }
                    JSONObject msgData = apiResultData.getJSONObject("msgData");
                    log.info("sf cancel order {}", msgData);
                    JSONArray waybillNoInfoList = msgData.getJSONArray("waybillNoInfoList");
                    for (int i = 0; i < waybillNoInfoList.size(); i++) {
                        JSONObject object = waybillNoInfoList.getJSONObject(i);
                        if (waybillId.equals(object.getString("waybillNo"))) {
                            return true;
                        }
                    }
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        if (DeliveryEnum.JD.toString().equals(deliveryId)) {
            try {
                Delivery config = deliveryService.getConfig(DeliveryEnum.JD.toString());
                List<OrderProduct> orderProductList = orderProductService.getOrderProductList(orderId);
                OrderProduct orderProduct = orderProductList.get(0);
                EcapV1OrdersCancelLopRequest request = new EcapV1OrdersCancelLopRequest();
                CommonOrderCancelRequest cancelRequest = new CommonOrderCancelRequest();
                cancelRequest.setWaybillCode(waybillId);
                cancelRequest.setCustomerOrderId(orderProduct.getOrderSerialNo());
                cancelRequest.setCustomerCode("029K3587670");
                cancelRequest.setOrderOrigin(1);
                cancelRequest.setCancelReason("取消");
                cancelRequest.setCancelReasonCode("1");
                LopPlugin lopPlugin = OAuth2PluginFactory.produceLopPlugin(config.getBizid(), config.getPassword(), config.getAuthCode());
                request.setUseJosAuth(false);
                request.addLopPlugin(lopPlugin);
                request.setRequest(cancelRequest);
                EcapV1OrdersCancelLopResponse response = defaultDomainApiClient.execute(request);
                if (response != null && response.getResult() != null) {
                    if (response.getResult().getSuccess()) {
                        CommonModifyCancelOrderResponse data = response.getResult().getData();
                        log.info("jd cancel order data {}", data);
                        String waybillCode = data.getWaybillCode();
                        Integer resultType = data.getResultType();
                        // 取消结果；枚举值：0 - 取消成功；1 - 拦截成功； 2 - 取消失败；3 - 拦截失败，调用成功一定返回
                        return resultType == 0 || resultType == 1;
                    } else {
                        throw new CustomException(response.getResult().getMsg());
                    }
                }
            } catch (LopException e) {
                e.printStackTrace();
                log.error("cancel order err{}", e);
            }
        }
        return null;
    }

    @Override
    public Boolean cancelSfOrder(String orderId, String deliveryId, String waybillId, String appid, String
            secret, String userId) {
        if (DeliveryEnum.SF.toString().equals(deliveryId)) {
            List<OrderProduct> orderProductList = orderProductService.getOrderProductList(orderId);
            String orderSerialNo = orderProductList.get(0).getOrderSerialNo();
            JSONObject body = new JSONObject();
            body.put("orderId", orderSerialNo);
            body.put("dealType", 2);
            try {
                String result = CallExpressSFHttpUtil.callSFApi("EXP_RECE_UPDATE_ORDER", body.toJSONString());
                if (StringUtils.isNotBlank(result)) {
                    JSONObject jsonObject = JSONObject.parseObject(result);
                    if (!"A1000".equals(jsonObject.getString("apiResultCode"))) {
                        throw new CustomException(jsonObject.getString("apiErrorMsg"));
                    }
                    JSONObject apiResultData = jsonObject.getJSONObject("apiResultData");
                    if (!apiResultData.getBoolean("success")) {
                        List<OrderLogisticStep> orderLogisticSteps = this.queryLogistic(orderId, deliveryId, waybillId, appid, secret, userId);
                        if (CollectionUtils.isEmpty(orderLogisticSteps)) {
                            return true;
                        }
                        throw new CustomException(apiResultData.getString("errorMsg"));
                    }
                    JSONObject msgData = apiResultData.getJSONObject("msgData");
                    log.info("sf cancel order {}", msgData);
                    JSONArray waybillNoInfoList = msgData.getJSONArray("waybillNoInfoList");
                    for (int i = 0; i < waybillNoInfoList.size(); i++) {
                        JSONObject object = waybillNoInfoList.getJSONObject(i);
                        if (waybillId.equals(object.getString("waybillNo"))) {
                            return true;
                        }
                    }
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public DeliveryStock queryStock(String deliveryId, String userId) {
        DeliveryStock deliveryStock = new DeliveryStock();
        if (DeliveryEnum.STO.toString().equals(deliveryId)) {
            Delivery delivery = deliveryService.getConfig("STO");
            if (delivery == null) {
                throw new CustomException("无法查询");
            }
            String bizid = delivery.getBizid();
            String str = buildSTOBillQueryUserStock(bizid.split("_")[0], bizid.split("_")[1], delivery.getPassword());
            log.info("sto queryStock res {}", str);
            JSONObject jsonObject = JSONObject.parseObject(str);
            if (jsonObject.getBoolean("success")) {
                deliveryStock.setRemainNum(jsonObject.getString("data"));
                return deliveryStock;
            } else {
                throw new CustomException(jsonObject.getString("errorMsg"));
            }
        }
        if (DeliveryEnum.YUNDA.toString().equals(deliveryId)) {
            Delivery delivery = deliveryService.getConfig("YUNDA");
            String str = this.searchCount(yundaexConfig.getAppkey(), delivery.getBizid(), delivery.getPassword(), null);
            log.info("yunda search count res {}", str);
            JSONObject jsonObject = JSONObject.parseObject(str);
            if ("0000".equals(jsonObject.getString("code")) && jsonObject.getBoolean("result")) {
                JSONArray data = jsonObject.getJSONArray("data");
                for (int i = 0; i < data.size(); i++) {
                    JSONObject object = data.getJSONObject(i);
                    deliveryStock.setRemainNum(object.getString("remain_num"));
                    deliveryStock.setFreeNum(object.getString("free_num"));
                    deliveryStock.setTotalNum(object.getString("total_num"));
                    deliveryStock.setUsedNum(object.getString("used_num"));
                }
                return deliveryStock;
            }
        }
        if (DeliveryEnum.JTSD.toString().equals(deliveryId)) {
            Delivery config = deliveryService.getConfig(DeliveryEnum.JTSD.toString());
            //把接口需要的参数封装到map
            Map<String, Object> map = new HashMap<>();
            map.put("customerCode", config.getBizid());
            //调用执行器,调用接口方法;
            try {
                com.alibaba.fastjson.JSONObject data = jtExpressApi.postByCustom(map, "https://openapi.jtexpress.com.cn/webopenplatformapi/api/ess/balance");
                if (data != null) {
                    if (data.getInteger("code") != 1) {
                        throw new CustomException(data.getString("msg"));
                    }
                    deliveryStock.setRemainNum(data.getJSONObject("data").getString("balance"));
                } else {
                    throw new CustomException("服务异常请重试");
                }
            } catch (IOException e) {
                e.printStackTrace();
                throw new CustomException("服务异常");
            }
        }
        return deliveryStock;
    }

    @Override
    public String logisticSubscribe(String deliveryId, OrderAddress senderAddress, OrderAddress receiverAddress, String orderSerialNo, String waybillId) {
        if (DeliveryEnum.YUNDA.toString().equals(deliveryId)) {
            final String url = "https://openapi.yundaex.com/openapi/outer/logictis/subscribe";
            JSONObject jsonParams = new JSONObject();
            JSONArray orders = new JSONArray();
            JSONObject order = new JSONObject();
            order.put("orderid", orderSerialNo);
            order.put("mailno", waybillId);
            JSONObject sender = new JSONObject();
            sender.put("name", senderAddress.getName());
            sender.put("province", senderAddress.getProvince());
            sender.put("city", senderAddress.getCity());
            sender.put("county", senderAddress.getArea());
            sender.put("address", senderAddress.getProvince() + "," + senderAddress.getCity() + "," + senderAddress.getArea() + "," + senderAddress.getTown() + senderAddress.getAddress());
            sender.put("mobile", senderAddress.getMobile());
            order.put("sender", sender);
            JSONObject receiver = new JSONObject();
            receiver.put("name", receiverAddress.getName());
            receiver.put("province", receiverAddress.getProvince());
            receiver.put("city", receiverAddress.getCity());
            receiver.put("county", receiverAddress.getArea());
            receiver.put("address", receiverAddress.getProvince() + "," + receiverAddress.getCity() + "," + receiverAddress.getArea() + "," + receiverAddress.getTown() + receiverAddress.getAddress());
            receiver.put("mobile", senderAddress.getMobile());
            order.put("receiver", receiver);
            orders.add(order);
            jsonParams.put("orders", orders);
            log.info("yunda subscribe order param {}", jsonParams);
            String logisticSubscribe = OpenApiHttpUtils.doPostJson(url, jsonParams.toString(), yundaexConfig.getAppkey(), yundaexConfig.getAppSecret());
            log.info("order subscribe result {}", logisticSubscribe);
            if (StringUtils.isNotBlank(logisticSubscribe)) {
                JSONObject object = JSONObject.parse(logisticSubscribe);
                if ("0000".equals(object.getString("code"))) {
                    JSONArray subcribeDataList = object.getJSONArray("data");
                    for (int j = 0; j < subcribeDataList.size(); j++) {
                        JSONObject subOrder = subcribeDataList.getJSONObject(j);
                        return subOrder.getString("result");
                    }
                }
            }
        }
        if (DeliveryEnum.JD.toString().equals(deliveryId)) {
            try {
                Delivery config = deliveryService.getConfig(DeliveryEnum.JD.toString());
                EcapV1OrdersTraceSubscribeLopRequest request = new EcapV1OrdersTraceSubscribeLopRequest();
                com.lop.open.api.sdk.domain.ECAP.CommonSubscribeTraceApi.commonSubscribeTraceV1.CommonSubscribeTraceRequest commonSubscribeTraceRequest = new com.lop.open.api.sdk.domain.ECAP.CommonSubscribeTraceApi.commonSubscribeTraceV1.CommonSubscribeTraceRequest();
                commonSubscribeTraceRequest.setCustomerCode("029K3587670");
                commonSubscribeTraceRequest.setWaybillCode(waybillId);
                commonSubscribeTraceRequest.setMobile(receiverAddress.getMobile().substring(receiverAddress.getMobile().length() - 4));
                LopPlugin lopPlugin = OAuth2PluginFactory.produceLopPlugin(config.getBizid(), config.getPassword(), config.getAuthCode());
                request.setUseJosAuth(false);
                request.addLopPlugin(lopPlugin);
                request.setRequest(commonSubscribeTraceRequest);
                EcapV1OrdersTraceSubscribeLopResponse response = defaultDomainApiClient.execute(request);
                if (response != null && response.getResult() != null && response.getResult().getSuccess()) {
                    CommonSubscribeResponse result = response.getResult();
                    log.info("jd subscribe order data {}", result);
                    return JSONObject.toJSONString(result);
                } else {
                    log.error("jd subcribe err {}", JSONObject.toJSONString(response.getResult()));
                }
            } catch (LopException e) {
                e.printStackTrace();
                log.error("jd subscribe order err{}", e);
            }
        }
        return null;
    }

    @Override
    public OrderProduct subscribeOrder(String orderId, String userId) {
        OrderVo order = orderService.getDetail(orderId);
        List<OrderProduct> orderProductList = orderProductService.getOrderProductList(order.getId());
        OrderProduct orderProduct = order.getProductList().get(0);
        String logisticSubscribe = this.logisticSubscribe(orderProduct.getDeliveryId(), orderProduct.getSendMan(), orderProduct.getRecMan(), orderProduct.getOrderSerialNo(), orderProduct.getWaybillId());
        orderProduct.setSubcribeResult(logisticSubscribe);
        orderProduct.setUpdateTime(new Date());
        orderProductService.update(orderProduct);
        return orderProduct;
    }

    @Override
    public Object getEMSWaybill(String waybillNo) {
        Delivery delivery = deliveryService.getConfig(DeliveryEnum.EMS.toString());
        JSONObject body = new JSONObject();
        body.put("waybillNo", waybillNo);
        body.put("type", "");//面单类型 129：总部模板76129 149：总部模板76149 179：总部模板100179
        body.put("getURL", "1");
        return EMSUtils.doPost("010004", delivery.getBizid(), delivery.getAuthCode(), body.toJSONString(), delivery.getPassword());
    }

    @Override
    public JSONObject print(String orderId, Long printerId, String userId, Long deptId) {
        if (StringUtils.isBlank(orderId) || printerId == null) {
            throw new CustomException("参数异常");
        }
        OrderVo order = orderService.getDetail(orderId);
        List<OrderProduct> orderProductList = order.getProductList();
        UserPrinter printer = printerService.get(printerId);
        if (printer == null) {
            throw new CustomException("打印机不存在!");
        }
//        if (StringUtils.isBlank(order.getProductCategory()))
//        String tempId = "201ea87f51c04576a8e5fd4200f68fb1";
//        String tempId = "265330fc52974d39b9d2517abe0cba92";
        CustomReq customReq = new CustomReq();
        customReq.setPrintType(PrintType.CLOUD);
        customReq.setTempId(order.getOrderType() == 1 ? "201ea87f51c04576a8e5fd4200f68fb1" : "265330fc52974d39b9d2517abe0cba92");
        customReq.setSiid(printer.getSiid());
        if (StringUtils.isNotBlank(printer.getDirection())) {
            //打印方向（默认0） 0-正方向 1-反方向；只有printType为CLOUD有作用
            customReq.setDirection(printer.getDirection());
        }
        Map<String, Object> customParam = new HashMap();
        if (order.getOrderType() == 1) {
            OrderProduct product = orderProductList.get(0);
            OrderAddress recMan = product.getRecMan();
            OrderAddress sendMan = product.getSendMan();
            customParam.put("waybillId", product.getWaybillId());
            customParam.put("bigWord", product.getBigWord());
            customParam.put("packagePlace", product.getPackagePlace());
            customParam.put("weight", product.getWeight());
            customParam.put("itemType", product.getItemType());
            customParam.put("itemNotes", product.getItemNotes());
            JSONObject sender = new JSONObject();
            sender.put("name", sendMan.getName());
            sender.put("mobile", sendMan.getMobile());
            sender.put("province", sendMan.getProvince());
            sender.put("city", sendMan.getCity());
            sender.put("area", sendMan.getArea());
            sender.put("address", sendMan.getTown() + sendMan.getAddress());
            JSONObject receiver = new JSONObject();
            receiver.put("name", recMan.getName());
            receiver.put("mobile", recMan.getMobile());
            receiver.put("province", recMan.getProvince());
            receiver.put("city", recMan.getCity());
            receiver.put("area", recMan.getArea());
            receiver.put("address", recMan.getTown() + recMan.getAddress());
            customParam.put("sendMan", sendMan);
            customParam.put("recMan", receiver);
        }
        if (order.getOrderType() == 2) {
            List<OrderAddress> addressList = orderAddressService.getAddressList(orderId);
            OrderAddress receiverAddress = addressList.stream().filter(orderAddress -> orderAddress.getType() == 2).findFirst().get();
            OrderAddress regimentAddress = addressList.stream().filter(orderAddress -> orderAddress.getType() == 3).findFirst().get();
            customParam.put("outTradeNo", order.getOutTradeNo().toUpperCase());
            customParam.put("totalPrice", order.getTotalPrice().toPlainString());
            customParam.put("num", orderProductList.size());
            JSONObject addressUser = new JSONObject();
            addressUser.put("name", receiverAddress.getName());
            addressUser.put("mobile", receiverAddress.getMobile());
            addressUser.put("province", receiverAddress.getProvince());
            addressUser.put("city", receiverAddress.getCity());
            addressUser.put("area", receiverAddress.getArea());
            addressUser.put("address", receiverAddress.getTown() + receiverAddress.getAddress());
            customParam.put("address_user", addressUser);
            JSONObject addressRegiment = new JSONObject();
            addressRegiment.put("name", regimentAddress.getName());
            addressRegiment.put("mobile", regimentAddress.getMobile());
            addressRegiment.put("province", regimentAddress.getProvince());
            addressRegiment.put("city", regimentAddress.getCity());
            addressRegiment.put("area", regimentAddress.getArea());
            addressRegiment.put("address", regimentAddress.getTown() + regimentAddress.getAddress());
            customParam.put("address_regiment", addressRegiment);
            JSONArray productList = new JSONArray();
            for (OrderProduct product : orderProductList) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("name", product.getName());
                jsonObject.put("pricePerUnit", product.getPricePerUnit());
                jsonObject.put("totalPrice", product.getTotalPrice());
                jsonObject.put("quantity", product.getQuantity());
                productList.add(jsonObject);
            }
            customParam.put("products", productList);
        }
        customReq.setCustomParam(customParam);
        String param = new Gson().toJson(customReq);
        log.info("order bill custom print param {}", param);
        String t = System.currentTimeMillis() + "";
        PrintReq printReq = new PrintReq();
        printReq.setT(t);
        printReq.setKey(key);
        printReq.setSign(SignUtils.printSign(param, t, key, secret));
        printReq.setMethod(ApiInfoConstant.CUSTOM);
        printReq.setParam(param);
        IBaseClient baseClient = new LabelV2();
        HttpResult httpResult = null;
        try {
            httpResult = baseClient.execute(printReq);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("print err -> {}", e);
            throw new CustomException("打印异常");
        }
        JSONObject data = null;
        if (httpResult.getStatus() == 200) {
            String body = httpResult.getBody();
            JSONObject jsonObject = JSONObject.parseObject(body);
            if (jsonObject.getInteger("code") == 200) {
                data = jsonObject.getJSONObject("data");
                int printTime = order.getPrintTimes() == null ? 0 : order.getPrintTimes();
                order.setPrintTimes(printTime + 1);
                order.setLastPrintTime(new Date());
                order.setPrinterId(printerId);
                order.setUpdateTime(new Date());
                order.setUpdateBy(userId);
                orderMapper.updateByPrimaryKey(order);
                log.info("task -> {}", data);
            } else {
                throw new CustomException(jsonObject.getString("message"));
            }
        } else {
            throw new CustomException("打印异常");
        }
        if (order.getOrderType() != null && order.getOrderType() == 2 && userId.equals(order.getRegimentId())) {
            for (OrderProduct orderProduct : orderProductList) {
                userOrderEventService.addInitEvent(userId, deptId, order.getId(), orderProduct.getId());
                orderLogisticsService.addOrderLogistics(orderId, orderProduct.getId(), 1, userId, deptId, true);
            }
        }
        return data;
    }


    @Override
    public JSONObject sfExpressQueryDelivertm(String businessType, BigDecimal weight, String consignedTime, String
            searchPrice, OrderAddress receiverAddress, OrderAddress senderAddress) {
        JSONObject body = new JSONObject();
        body.put("weight", weight.setScale(2, RoundingMode.HALF_UP));
        body.put("searchPrice", searchPrice == null ? "1" : searchPrice);
        body.put("consignedTime", consignedTime);
        body.put("businessType", businessType == null ? "2" : businessType);

        JSONObject destAddress = new JSONObject();
        destAddress.put("province", receiverAddress.getProvince());
        destAddress.put("city", receiverAddress.getCity());
        destAddress.put("district", receiverAddress.getArea());
        destAddress.put("address", receiverAddress.getProvince() + "," + receiverAddress.getCity() + "," + receiverAddress.getArea() + "," + receiverAddress.getTown() + receiverAddress.getAddress());
        body.put("destAddress", destAddress);
        JSONObject srcAddress = new JSONObject();
        srcAddress.put("province", senderAddress.getProvince());
        srcAddress.put("city", senderAddress.getCity());
        srcAddress.put("district", senderAddress.getArea());
        srcAddress.put("address", senderAddress.getProvince() + "," + senderAddress.getCity() + "," + senderAddress.getArea() + "," + senderAddress.getTown() + senderAddress.getAddress());
        body.put("srcAddress", srcAddress);
        try {
            String queryDelivertm = CallExpressSFHttpUtil.callSFApi("EXP_RECE_QUERY_DELIVERTM", body.toJSONString());
            if (StringUtils.isNotBlank(queryDelivertm)) {
                JSONObject jsonObject = JSONObject.parseObject(queryDelivertm);
                if (!"A1000".equals(jsonObject.getString("apiResultCode"))) {
                    throw new CustomException(jsonObject.getString("apiErrorMsg"));
                }
                JSONObject apiResultData = jsonObject.getJSONObject("apiResultData");
                if (!apiResultData.getBoolean("success")) {
                    throw new CustomException(apiResultData.getString("errorMsg"));
                }
                JSONObject msgData = apiResultData.getJSONObject("msgData");
                log.info("sf query order {}", msgData);
                return msgData;
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public CommonActualFeeResponse queryJDActualFee(String waybillId) {
        Delivery config = deliveryService.getConfig(DeliveryEnum.JD.toString());
        try {
            EcapV1OrdersActualfeeQueryLopRequest request = new EcapV1OrdersActualfeeQueryLopRequest();
            com.lop.open.api.sdk.domain.ECAP.CommonQueryOrderApi.commonGetActualFeeInfoV1.CommonActualFeeRequest commonActualFeeRequest = new com.lop.open.api.sdk.domain.ECAP.CommonQueryOrderApi.commonGetActualFeeInfoV1.CommonActualFeeRequest();
            commonActualFeeRequest.setWaybillCode(waybillId);
            commonActualFeeRequest.setOrderOrigin(1);
            commonActualFeeRequest.setCustomerCode("029K3587670");
            LopPlugin lopPlugin = OAuth2PluginFactory.produceLopPlugin(config.getBizid(), config.getPassword(), config.getAuthCode());
            request.setUseJosAuth(false);
            request.addLopPlugin(lopPlugin);
            request.setRequest(commonActualFeeRequest);
            EcapV1OrdersActualfeeQueryLopResponse response = defaultDomainApiClient.execute(request);
            if (response != null && response.getResult() != null) {
                CommonActualFeeResponse data = response.getResult().getData();
                log.info("jd create order data {}", data);
                return data;
            }
        } catch (LopException e) {
            e.printStackTrace();
            log.error("check pre err{}", e);
        }
        return null;
    }

    @Override
    public CommonCheckPreCreateOrderResponse jdPreCheck(String deliveryId, OrderAddress senderAddress, OrderAddress receiverAddress, String name, Integer quantity, BigDecimal volume, BigDecimal weight, String expressType) {
        if (DeliveryEnum.JD.toString().equals(deliveryId)) {
            try {
                Delivery config = deliveryService.getConfig(DeliveryEnum.JD.toString());
                EcapV1OrdersPrecheckLopRequest request = new EcapV1OrdersPrecheckLopRequest();
                CommonCreateOrderRequest commonCreateOrderRequest = new CommonCreateOrderRequest();
                Contact senderContact = new Contact();
                senderContact.setFullAddress(senderAddress.getProvince() + senderAddress.getCity() + senderAddress.getArea() + senderAddress.getAddress());
                Contact receiverContact = new Contact();
                receiverContact.setFullAddress(receiverAddress.getProvince() + receiverAddress.getCity() + receiverAddress.getArea() + receiverAddress.getAddress());
                commonCreateOrderRequest.setOrderOrigin(1);
                commonCreateOrderRequest.setSenderContact(senderContact);
                commonCreateOrderRequest.setReceiverContact(receiverContact);
                java.util.List<com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCheckPreCreateOrderV1.CommonCargoInfo> cargoes = new ArrayList<>();
                com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCheckPreCreateOrderV1.CommonCargoInfo cargoInfo = new com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCheckPreCreateOrderV1.CommonCargoInfo();
                cargoInfo.setName(name);
                cargoInfo.setQuantity((quantity == null || quantity < 0) ? 1 : quantity);
                cargoInfo.setVolume(volume == null ? null : volume.setScale(2, BigDecimal.ROUND_HALF_UP));
                cargoInfo.setWeight(weight);
                cargoes.add(cargoInfo);
                commonCreateOrderRequest.setCargoes(cargoes);
                com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCheckPreCreateOrderV1.CommonProductInfo commonProductInfo = new com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCheckPreCreateOrderV1.CommonProductInfo();
                commonProductInfo.setProductCode("1".equals(expressType) ? "ed-m-0001" : "ed-m-0059");
                commonCreateOrderRequest.setProductsReq(commonProductInfo);
                commonCreateOrderRequest.setCustomerCode("029K3587670");
                LopPlugin lopPlugin = OAuth2PluginFactory.produceLopPlugin(config.getBizid(), config.getPassword(), config.getAuthCode());
                request.setUseJosAuth(false);
                request.addLopPlugin(lopPlugin);
                request.setRequest(commonCreateOrderRequest);
                EcapV1OrdersPrecheckLopResponse response = defaultDomainApiClient.execute(request);
                log.info("check pre data {}", response);
                if (response != null && response.getResult() != null) {
                    if (response.getResult().getCode() != 0) {
                        throw new CustomException(response.getResult().getMsg());
                    }
                    CommonCheckPreCreateOrderResponse data = response.getResult().getData();
                    return data;
                }
            } catch (LopException e) {
                e.printStackTrace();
                log.error("check pre err{}", e);
            }
        }
        return null;
    }

    @Override
    public String realName(String delivery, String name, String valididcardCode, String phone, String address) {
        if (DeliveryEnum.JTSD.toString().equalsIgnoreCase(delivery)) {
            String url = "https://openapi.jtexpress.com.cn/webopenplatformapi/api/realName/saveOrUpdate";
            Map<String, Object> map = new HashMap<>(5);
            map.put("name", name);
            map.put("typeOfId", "01");
            map.put("numberOfId", valididcardCode);
            map.put("phone", phone);
            map.put("typeOfUser", "1");
            try {
                log.info("极兔实名 {}", JSONObject.toJSONString(map));
                com.alibaba.fastjson.JSONObject jsonObject = jtExpressApi.postByCustom(map, url);
                log.info("极兔实名 {}", jsonObject);
                return jsonObject.toJSONString();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (DeliveryEnum.STO.toString().equalsIgnoreCase(delivery)) {
            JSONObject content = new JSONObject(8);
            content.put("name", name);
            content.put("valididcardType", "01");//"01", //证件类型 （01：居民身份证 02：临时居民身份证 03：户口薄 04：中国人民解放军军人身份证 05：中国人民武装警察身份证 06：港澳居民来往内地 通行证 07：台湾居民来往大陆通行证 08：外国公民护照 09: 中国公民护照)
            content.put("valididcardCode", valididcardCode);
            content.put("mobilephone", phone);
            content.put("siteCode", "716000");
            content.put("settleObjectCode", "716299");
            content.put("addressDetailed", address);
            JSONObject publicParam = new JSONObject();
            publicParam.put("api_name", "STO_MARKET_REAL_NAME_AUTH");
            publicParam.put("content", content.toString());
            publicParam.put("from_appkey", stoConfig.getAppKey());
            publicParam.put("from_code", stoConfig.getCode());
            publicParam.put("to_appkey", "marketKmsAsync");
            publicParam.put("to_code", "market_kms_async");
            publicParam.put("data_digest", getSignature(content.toString(), stoConfig.getSecretKey()));
            log.info("sto check param {}", publicParam);
            String post = HttpUtil.post(STO_URL, publicParam);
            log.info("sto real name res {}", post);
            return post;
        }
        return null;
    }

    private JSONObject sfExpressQuerOrderResp(String sfOrderId, String mainWaybillNo) {
        JSONObject body = new JSONObject();
        body.put("orderId", sfOrderId);
        if (mainWaybillNo != null) {
            body.put("mainWaybillNo", mainWaybillNo);
        }
        body.put("language", "zh-CN");
        try {
            String searchOrderResp = CallExpressSFHttpUtil.callSFApi("EXP_RECE_SEARCH_ORDER_RESP", body.toJSONString());
            if (StringUtils.isNotBlank(searchOrderResp)) {
                JSONObject jsonObject = JSONObject.parseObject(searchOrderResp);
                if (!"A1000".equals(jsonObject.getString("apiResultCode"))) {
                    throw new CustomException(jsonObject.getString("apiErrorMsg"));
                }
                JSONObject apiResultData = jsonObject.getJSONObject("apiResultData");
                if (!apiResultData.getBoolean("success")) {
                    throw new CustomException(apiResultData.getString("errorMsg"));
                }
                JSONObject msgData = apiResultData.getJSONObject("msgData");
                log.info("sf query price {}", msgData);
                return msgData;
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    private String yundaCancelBmOrder(String partnerId, String secret, String mailno) {
        final String url = "https://openapi.yundaex.com/openapi-api/v1/accountOrder/cancelBmOrder";
        JSONObject jsonParams = new JSONObject();
        jsonParams.put("appid", yundaexConfig.getAppkey());
        jsonParams.put("partner_id", partnerId);//韵达白马账号（合作网点提供）
        jsonParams.put("secret", secret);//韵达白马账号的联调密码（合作网点提供）
        JSONArray orderList = new JSONArray();
        JSONObject orderItem = new JSONObject();
        orderItem.put("order_serial_no", "ELEMENT_" + IdUtil.getSnowflakeNextIdStr());
        orderItem.put("mailno", mailno);
        orderList.add(orderItem);
        jsonParams.put("orders", orderList);
        log.info("yunda cancel bm param {}", jsonParams);
        return OpenApiHttpUtils.doPostJson(url, jsonParams.toString(), yundaexConfig.getAppkey(), yundaexConfig.getAppSecret());
    }

    private String yundaLogisicQuery(String mailno) {
        final String url = "https://openapi.yundaex.com/openapi/outer/logictis/query";
        JSONObject jsonParams = new JSONObject();
        jsonParams.put("mailno", mailno);
        log.info("yunda query logistic param {}", jsonParams);
        return OpenApiHttpUtils.doPostJson(url, jsonParams.toString(), yundaexConfig.getAppkey(), yundaexConfig.getAppSecret());
    }

    private String buildSTOBillQueryUserStock(String siteCode, String userCode, String password) {
        JSONObject content = new JSONObject();
        content.put("siteCode", siteCode);
        content.put("userCode", userCode);
        content.put("password", password);
        content.put("userType", 0);//客户类型（0：客户 1：业务员）默认0
        content.put("timestamp", System.currentTimeMillis());
        JSONObject publicParam = new JSONObject();
        publicParam.put("api_name", "BILL_CODE_QUERY_USER_STOCK");
        publicParam.put("content", content);
        publicParam.put("from_appkey", stoConfig.getAppKey());
        publicParam.put("from_code", stoConfig.getCode());
        publicParam.put("to_appkey", "billcode_open");
        publicParam.put("to_code", "billcode_open");
        publicParam.put("data_digest", getSignature(content.toJSONString(), stoConfig.getSecretKey()));
        log.info("sto query stock param {}", publicParam);
        return HttpUtil.post(STO_URL, publicParam);
    }

    private String buildSTOOrderCancel(String billCode) {
        JSONObject content = new JSONObject();
        content.put("billCode", billCode);
        content.put("orderSource", STO_ORDER_SOURCE);
        content.put("orderType", "01");
        JSONObject publicParam = new JSONObject();
        publicParam.put("api_name", "EDI_MODIFY_ORDER_CANCEL");
        publicParam.put("content", content.toString());
        publicParam.put("from_appkey", stoConfig.getAppKey());
        publicParam.put("from_code", stoConfig.getCode());
        publicParam.put("to_appkey", "edi_modify_order");
        publicParam.put("to_code", "edi_modify_order");
        publicParam.put("data_digest", getSignature(content.toString(), stoConfig.getSecretKey()));
        log.info("sto check param {}", publicParam);
        return HttpUtil.post(STO_URL, publicParam);
    }

    private String buildSTOTraceQuery(String waybillNo) {
        JSONObject content = new JSONObject();
        content.put("order", "asc");
        JSONArray waybill = new JSONArray();
        waybill.add(waybillNo);
        content.put("waybillNoList", waybill);
        JSONObject publicParam = new JSONObject();
        publicParam.put("api_name", "STO_TRACE_QUERY_COMMON");
        publicParam.put("content", content.toString());
        publicParam.put("from_appkey", stoConfig.getAppKey());
        publicParam.put("from_code", stoConfig.getCode());
        publicParam.put("to_appkey", "sto_trace_query");
        publicParam.put("to_code", "sto_trace_query");
        publicParam.put("data_digest", getSignature(content.toString(), stoConfig.getSecretKey()));
        log.info("sto check param {}", publicParam);
        return HttpUtil.post(STO_URL, publicParam);
    }

    private String buildExpressOrder(String goodsName, String weight, OrderAddress senderAddress, OrderAddress receiverAddress, Delivery deliveryConfig) {
        JSONObject content = new JSONObject();
        content.put("orderNo", IdUtil.getSnowflakeNextIdStr());
        content.put("orderSource", STO_ORDER_SOURCE);
        content.put("billType", "00");//获取面单的类型（00-普通、03-国际、01-代收、02-到付、04-生鲜），默认普通业务，如果有其他业务先与业务方沟通清楚
        content.put("orderType", "01");//订单类型（01-普通订单、02-调度订单）默认01-普通订单，如果有散单业务需先业务方沟通清楚
        JSONObject sender = new JSONObject();
        sender.put("name", StringUtils.isNotBlank(senderAddress.getRealName()) && !senderAddress.getRealName().equals(senderAddress.getName()) ? senderAddress.getRealName() + "(" + senderAddress.getName() + ")" : senderAddress.getRealName());
        sender.put("mobile", senderAddress.getMobile());
        sender.put("postCode", senderAddress.getCode());
        sender.put("country", "中国");
        sender.put("province", senderAddress.getProvince());
        sender.put("city", senderAddress.getCity());
        sender.put("area", senderAddress.getArea());
        sender.put("town", senderAddress.getTown());
        sender.put("address", senderAddress.getAddress());
        content.put("sender", sender);
        JSONObject receiver = new JSONObject();
        receiver.put("name", receiverAddress.getName());
        receiver.put("mobile", receiverAddress.getMobile());
        receiver.put("postCode", receiverAddress.getCode());
        receiver.put("country", "中国");
        receiver.put("province", receiverAddress.getProvince());
        receiver.put("city", receiverAddress.getCity());
        receiver.put("area", receiverAddress.getArea());
        receiver.put("town", receiverAddress.getTown());
        receiver.put("address", receiverAddress.getAddress());
        content.put("receiver", receiver);
        JSONObject cargo = new JSONObject();
        cargo.put("battery", "10");//带电标识 （10/未知 20/带电 30/不带电）
        cargo.put("goodsType", "大件");//物品类型（大件、小件、扁平件\文件）
        cargo.put("goodsName", goodsName);//物品名称
        cargo.put("weight", weight);//重量(kg)
        content.put("cargo", cargo);
        JSONObject customer = new JSONObject();
        String bizId = deliveryConfig.getBizid();
        customer.put("siteCode", bizId.split("_")[0]);
        customer.put("customerName", bizId.split("_")[1]);
        customer.put("sitePwd", deliveryConfig.getPassword());// 电子面单密码
        content.put("customer", customer);
        content.put("timelessType", "01");//时效类型（01-普通）
        content.put("productType", "01");//产品类型 （01-普通、02-冷链、03-生鲜）
        content.put("remark", goodsName);//备注
        content.put("expressDirection", "01");//快递流向（01-正向订单)默认01
        content.put("createChannel", "01");//创建原因（01-客户创建）默认01
        content.put("regionType", "01");//区域类型（01-国内）默认01
        content.put("payModel", "1");//支付方式（1-现付；2-到付；3-月结）
        JSONObject publicParam = new JSONObject();
        publicParam.put("api_name", "OMS_EXPRESS_ORDER_CREATE");
        publicParam.put("content", content.toString());
        publicParam.put("from_appkey", stoConfig.getAppKey());
        publicParam.put("from_code", stoConfig.getCode());
        publicParam.put("to_appkey", "sto_oms");
        publicParam.put("to_code", "sto_oms");
        publicParam.put("data_digest", getSignature(content.toString(), stoConfig.getSecretKey()));
        log.info("sto check param {}", publicParam);
        return HttpUtil.post(STO_URL, publicParam);
    }


    private String platformSortationAddressOutOfDelivery(LogisticCheckAddress senderAddress, LogisticCheckAddress
            receiverAddress) {
        JSONObject content = new JSONObject();
        content.put("requestUUID", IdUtil.getSnowflakeNextIdStr());
        content.put("customerName", "陕西延安公司_延安市宝塔区曌阳工贸有限责任公司");
        JSONObject sendAddress = new JSONObject();
        sendAddress.put("provinceName", senderAddress.getProvince());
        sendAddress.put("cityName", senderAddress.getCity());
        sendAddress.put("areaName", senderAddress.getArea());
        sendAddress.put("townName", senderAddress.getArea());
        sendAddress.put("detailAddress", senderAddress.getAddress());
        content.put("sendAddress", sendAddress);
        JSONObject consigneeAddress = new JSONObject();
        consigneeAddress.put("provinceName", receiverAddress.getProvince());
        consigneeAddress.put("cityName", receiverAddress.getCity());
        consigneeAddress.put("areaName", receiverAddress.getArea());
        consigneeAddress.put("townName", receiverAddress.getArea());
        consigneeAddress.put("detailAddress", receiverAddress.getAddress());
        content.put("consigneeAddress", consigneeAddress);
        JSONObject publicParam = new JSONObject();
        publicParam.put("api_name", "PLATFORM_SORTATION_ADDRESS_OUT_OF_DELIVERY");
        publicParam.put("content", content.toString());
        publicParam.put("from_appkey", stoConfig.getAppKey());
        publicParam.put("from_code", stoConfig.getCode());
        publicParam.put("to_appkey", "sto_sortation");
        publicParam.put("to_code", "sto_sortation");
        publicParam.put("data_digest", getSignature(content.toString(), stoConfig.getSecretKey()));
        log.info("sto check param {}", publicParam);
        String res = HttpUtil.post(STO_URL, publicParam);
        return res;
    }

    public static String getSignature(String content, String secretKey) {
        String text = content + secretKey;
        byte[] md5 = DigestUtils.md5Digest(text.getBytes());
        return Base64.encodeBase64String(md5);
    }
}
